// test.cpp : Defines the entry point for the console application.
//

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "rfc3280.h"
#include "a2c.h"

#define TRUE 1

extern A2C_OBJECT_SET ContentTypes;

extern A2C_COMPONENT_RELATIONS ItemInfo;


int main(int argc, char * argv[])
{
    char *	szObjectType = argv[1];
    FILE *	fp;
    size_t	cb;
    int		flags = 0;
    BYTE	rgb[1024*8];
    void *	pv = NULL;
    A2C_DESCRIPTOR const * pdesc = NULL;
    A2C_CONTEXT * pcxt = NULL;
    A2C_ERROR	err;

	CMS_ContentInfo ct = {"1.2.840.113549.1.7.2"};
	CMS_SignedData sd;

	Cert_Certificate cert;


    /*
     *  Command line for this program is
     *   <prog> <Object Type> <Input File> <Output File> <Print File>
     */

    if (argc != 5) {
        fprintf(stderr, "Command line: test <Object Type> <Input File> <Output File> <Print File>\n");
        exit(-1);
    }

    if (strcmp(szObjectType, "Certificate") == 0) {
        pdesc = &Cert_Certificate_descriptor;
    }
	else if (strcmp(szObjectType, "CMS") == 0) {
		pdesc = &CMS_ContentInfo_descriptor;
	}
    else {
        fprintf(stderr, "Legal Object Types are: Certificate, CMS");
        exit(1);
    }

    /*
     *  Open the source file for decoding
     */

    fp = fopen(argv[2], "rb");
    if (fp == NULL) {
        fprintf(stderr, "Cannot open the file '%s'\n", argv[2]);
        exit(1);
    }

    /*
     *  Start the decode operation
     */

    while (TRUE) {
        /*
         *  Read in a buffer of data to be decoded
         */
            
        cb = fread(rgb, 1, sizeof(rgb), fp);
        if (cb == 0) break;

        /*
         *  Make a call into the decoder
         */

        err = A2C_DecodeBer(&pv, pdesc, flags, &pcxt, rgb, cb);

        /*
         *  If we failed, and it was not a need more data error
         *      then exit and complain about it
         */
        
        if ((err < A2C_ERROR_Success) && (err != A2C_ERROR_needMoreData)) {
            fprintf(stderr, "Decode operation failed with %d\n", err);
            exit(err);
        }

        /*
         *  If we call in again - we will be doing a more data call
         */

        flags |= A2C_FLAGS_MORE_DATA;
    }

    /*
     *  Close input file
     */

    fclose(fp);

    /*
     *  Now lets create a text version and dump it out
     */

    fp = fopen(argv[4], "wt");
    if (fp == NULL) {
        fprintf(stderr, "Cannot create file '%s'\n", argv[4]);
        exit(1);
    }

    {
        BYTE* pb;
        int cb;

        /*
         *  Create a stream to write the data onto
         */

        A2C_STREAM * pstm2;
		
		A2C_CreateMemoryStream(&pstm2);

        /*
         *  Create the pretty print version
         */

        A2C_Print(pv, pdesc, pstm2);

        /*
         *  Retrieve the buffer holding the pretty print
         *      version from the stream object
         */
	
        pstm2->pfnGetData(pstm2, &pb, &cb);

        /*
         *  Bullet proof the terminator, that should already exist
         */
        
        pb[cb] = 0;

        /*
         *  Print into the file - not that for UTF8 this is an incorrect call
         */
        
        fprintf(fp, (char *) pb);
    }

    /*
     *  close the pretty print file
     */
    
    fclose(fp);

    /*
     * Now lets encode the object
     */

    {
        PBYTE pb;
        int cb;

        /*
         *  Create a stream to do the encode operation into
         */
        
        A2C_STREAM * pstm;
		
		A2C_CreateMemoryStream(&pstm);

        /*
         *  Do the encode operation
         */

        err = A2C_EncodeDer(pv, pdesc, 0, NULL, pstm);

        /*
         *  If it failed - compain and exit
         */
        
        if (err < A2C_ERROR_Success) {
            fprintf(stderr, "Encode operation failed with %d\n", err);
            exit(err);
        }

        /*
         *  Create the buffer to write to
         */

        fp = fopen(argv[3], "wb");
        if (fp == NULL) {
            fprintf(stderr, "Cannot open file '%s'\n", argv[3]);
            exit(-1);
        }

        /*
         *  Get the data from the stream object and dump into the file
         */

        pstm->pfnGetData(pstm, &pb, &cb);

        fwrite(pb, 1, cb, fp);

        /*
         *  Finished - close the file
         */
        
        fclose(fp);
    }

    return 0;
}



/********************************************* TEST CODE ********************************************/

